#include "commands.h"
 
// 命令解析模块 - 将用户输入转换为结构化命令
int parse_input(const char *input, ParsedCommand *out)
{
    // 验证输入的有效性
    if (input == NULL || out == NULL)
    {
        return -1;
    }
    char cmd_buf[16] = {0};
    out->has_args = 0; // 默认无参数

    // 安全分割命令和参数（防止缓冲区溢出）
    if (sscanf(input, "%15s %255[^\n]", cmd_buf, out->args) >= 1)
    {
        out->has_args = (strlen(out->args) > 0);
    }

    // 命令匹配（可扩展）
    if (strcmp(cmd_buf, "ls") == 0) out->cmd_type = CMD_LS;             // 显示目录信息
    else if (strcmp(cmd_buf, "cd") == 0) out->cmd_type = CMD_CD;        // 更改工作路径
    else if (strcmp(cmd_buf, "pwd") == 0) out->cmd_type = CMD_PWD;      // 显示当前路径
    else if (strcmp(cmd_buf, "rmove") == 0) out->cmd_type = CMD_RMOVE;  // 移动文件
    else if (strcmp(cmd_buf, "mkdir") == 0) out->cmd_type = CMD_MKDIR;  // 创建目录
    else if (strcmp(cmd_buf, "rmdir") == 0) out->cmd_type = CMD_RMDIR;  // 移除目录
    else if (strcmp(cmd_buf, "gets") == 0) out->cmd_type = CMD_GETS;    // 下载文件
    else if (strcmp(cmd_buf, "puts") == 0) out->cmd_type = CMD_PUTS;    // 上传文件
    else if (strcmp(cmd_buf, "exit") == 0 || strcmp(cmd_buf, "quit") == 0)
         out->cmd_type = CMD_EXIT;      // 退出请求
    else out->cmd_type = CMD_ILLEGAL;   // 非法命令
    return 0;
}

// 处理LS命令响应（目录列表）
int handle_ls_response(ClientContext *ctx, const protocol_header_t *header,const char *data)
{
    // 显示当前目录（从上下文缓存中获取）
    // printf("当前目录: %s\n", ctx->current_dir);
    // data字符串解析
    parseLsResp(data,strlen(data));
    return 0;
}
// 判断解析出的字符串是目录信息还是项名
int getTypeDirInfo(const char *input){
    if(strcmp(input,"dir_name") == 0) return 1;
    else if(strcmp(input,"dir_category") == 0) return 2;
    else if(strcmp(input,"dir_size") == 0) return 3;
    else if(strcmp(input,"last_modify_time") == 0) return 4;
    else return 0;
}
// 解析单项--输出
int parseDirInfo(char *dir_info){
    if(dir_info == NULL) return -1;

    char *token;
    char *saveptr;
    token = strtok_r(dir_info,":",&saveptr);
    int info_type;

    while(token != NULL){
        info_type = getTypeDirInfo(token);
        token = strtok_r(NULL,"",&saveptr);
        switch(info_type){
            case 1:
                printf("%-20s",token);
                break;
            case 2:
                printf("%-15s",token);
                break;
            case 3: 
                printf("%-10s",token);
                break;
            case 4:
                printf("%-20s",token);
        }
    }
    return 0;
}
// 解析命令--单项
int parseLsResp(const char *input, int input_length){
    // 动态申请，防止传入字符串过长，导致栈溢出，需要在函数退出前手动释放
    char *cur_input = (char *)calloc(input_length,sizeof(char));// 用来分割，会被修改
    if(cur_input == NULL){
        perror("parse_ls_resp:cur_input calloc.\n");
        return -1;
    }
    char *free_input = cur_input;// 用来释放堆空间

    // 用strtok_r分割字符串
    char *ret = strcpy(cur_input,input);
    if(ret == NULL){
        perror("parse_ls_resp: input to cur_input strcpy.\n");
        return -1;
    }
    int dir_count = 0;// 用来记录目录项的个数
    char *token;
    char *saveptr;

    char *size_dir = strtok_r(cur_input,",{}",&saveptr);// 处理开头的size字段
    if(size_dir == NULL){
        printf("input invalibal.\n");
        return 0;
    }
    token = strtok_r(NULL,"{,}",&saveptr);

    // 输出表头
    printf("%-6s%-20s%-15s%-10s%-20s \n",
            "ID","NAME","TYPE:","SIZE:","LAST_MODIFIDE");

    // printf("befor strtok\n");
    while(token != NULL){
        dir_count++;
        printf("%-6d",dir_count);
        for(int i=0;i<4;++i){
            if(token != NULL){
                // dir_info:data
                // printf("%s \n",token);
                // 分割单项
                parseDirInfo(token);
            }
            token = strtok_r(NULL,"{,}",&saveptr);
        }
        printf("\n");// 每输出完一个目录项就换行
    }
    printf("总计：%-4d\n",dir_count);

    // printf("after strtok\n");

    free(free_input);
    return 0;
}


/* 处理CD命令响应 */
int handle_cd_response(ClientContext *ctx, const protocol_header_t *header, const char *data){
    if(header->resp_type == FAIL){
        printf("服务端返回：当前目录切换失败.\n");
        return -1;
    }
    else if(header->resp_type == SUCESS){
        // 目标路径：p_cmd.args
        printf("当前目录切换成功.\n");
    }
    return 0;
}

/* 处理PWD命令响应（当前路径） */
int handle_pwd_response(ClientContext *ctx, const protocol_header_t *header,const char *data)
{
    if (header->data_length > 0)
    {
        // 安全拷贝目录路径（防止溢出）                    
        strncpy(ctx->current_dir, data, sizeof(ctx->current_dir) - 1);
        ctx->current_dir[sizeof(ctx->current_dir) - 1] = '\0';

        printf("当前目录: %s\n", ctx->current_dir);
    }
    return 0;
}
